use std::{fmt, ops, convert, marker, cmp};
use std::str::FromStr;
use std::num::ParseFloatError;

pub trait Skynet<T>:
    FromStr<Err = ParseFloatError>
    + ops::Add<Output = T>
    + ops::Div<Output = T>
    + convert::From<f64>
    + marker::Copy
    + ops::Sub<Output = T>
    + ops::Mul<Output = T>
    + ops::AddAssign
    + ops::DivAssign
    + cmp::PartialOrd
    + fmt::Display {
        fn inv(self) -> T;
        fn sqrt(self) -> T;
        fn sin(self) -> T;
        fn cos(self) -> T;
        fn abs(self) -> T;
}

impl Skynet<f64> for f64 {
    fn inv(self) -> f64 {
        -self
    }
    fn sqrt(self) -> f64 {
        self.sqrt()
    }
    fn sin(self) -> f64 {
        self.sin()
    }
    fn cos(self) -> f64 {
        self.cos()
    }
    fn abs(self) -> f64 {
        self.abs()
    }
}
